#include "mainwindow.h"
#include <QIcon>
#include <QMessageBox>
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <string>
#include <QTimer>

#include "tcp_interface.h"
#include "interpolator.h"
#include "g_code.h"
#include "sys.h"
extern DDA_Interpolator_t MainInterpolator;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    UI_Init();
    WorkGraphActive();
    TimerInit();
    this->SignalConfig();
    g_code_handler_init();
    C_CallbackConfig();
}

MainWindow::~MainWindow()
{

}

void MainWindow::PlotUpdate_Slot()
{
    widgetDrawArea->replot(QCustomPlot::rpQueuedReplot);
}

void MainWindow::Interpolate_Slot()
{
    if((Flags & FLAG_PAUSE_MASK) == FLAG_PAUSE_FALSE)
    {
        interpolator_Handler();
    }
    if(((Flags & FLAG_START_MASK) == FLAG_START_TRUE)&&(MainInterpolator.flags & 1) && ((g_code_translator_flags & G_CODE_TRANSLATOR_FLAG_OK_MASK)==G_CODE_TRANSLATOR_FLAG_OK_TRUE))
    {
        SelectNextLine();
    }
}


void MainWindow::TimerInit()
{
    FlushTimer = new QTimer(this);
    InterpolateTimer = new QTimer(this);
    FlushTimer->setInterval(17);
    InterpolateTimer->setInterval(5);
    FlushTimer->start();
    InterpolateTimer->start();
}

void MainWindow::ProcessGCodeFormQString(QString *qstring)
{
    std::string StdString;
    char *g_code_line_char;
    g_code_param_t ret_param;
    StdString = qstring->toStdString();
    g_code_line_char = const_cast<char*>(StdString.c_str());
    qDebug()<<g_code_line_char;
    g_code_get_param(g_code_line_char,&ret_param);
    Flags &= ~FLAG_CNC_BUSY_MASK;
    Flags |= FLAG_CNC_BUSY_TRUE;
}

void MainWindow::SetStatusSignal(int status)
{
    switch (status) {
    case 10:
        coolingStatus=0;CoolingStatusImage->setPixmap(pixMapRed);
        break;
    case 11:
        coolingStatus=1;CoolingStatusImage->setPixmap(pixMapGreen);
        break;
    case 0:
        mainshaftStatus=0;MainsharftStatusImage->setPixmap(pixMapRed);
        break;
    case 1:
        mainshaftStatus=1;MainsharftStatusImage->setPixmap(pixMapGreen);
    default:
        break;
    }
}

void MainWindow::SignalConfig(void)
{
    connect(act_open,&QAction::triggered,this,&MainWindow::openFile);
    connect(lineEdit_MDI,&QLineEdit::returnPressed,this,&MainWindow::MDI_Enter_Slot);
    connect(FlushTimer,&QTimer::timeout,this,&MainWindow::PlotUpdate_Slot);
    connect(InterpolateTimer,&QTimer::timeout,this,&MainWindow::Interpolate_Slot);
    connect(act_start,&QAction::triggered, this, &MainWindow::Start_Slot);
    connect(act_close,&QAction::triggered,this,&MainWindow::Close_Slot);
    connect(act_pause,&QAction::triggered,this,&MainWindow::Pause_Slot);
    connect(act_stop,&QAction::triggered,this,&MainWindow::Stop_Slot);
    /*
    connect(client,&QTcpSocket::readyRead,this,&MainWindow::TCP_Recieve_Slots);
    connect(client,&QTcpSocket::connected,this,&MainWindow::TCP_Connected_Slots);
    connect(client,&QTcpSocket::disconnected,this,&MainWindow::TCP_Disconnected_Slots);*/
}

void MainWindow::Start_Slot()
{
    QString Line;
    if((Flags & FLAG_PAUSE_MASK) != FLAG_PAUSE_TRUE)
    {
        Line = G_Code_list[current_line];
        ProcessGCodeFormQString(&Line);
        Flags &= ~FLAG_START_MASK;
        Flags |= FLAG_START_TRUE;
    }
    else
    {
        Flags &= ~FLAG_PAUSE_MASK;
        Flags |= FLAG_PAUSE_FALSE;
    }
}

void MainWindow::Pause_Slot()
{
    Flags &= ~FLAG_PAUSE_MASK;
    Flags |= FLAG_PAUSE_TRUE;
}

void MainWindow::Stop_Slot()
{
    MainInterpolator.flags |= 0x01;
    extern_INTERPOLATOR_CANCLE();
    Flags &= ~FLAG_CNC_BUSY_MASK;
    Flags |= FLAG_CNC_BUSY_FALSE;
    Flags &= ~FLAG_START_MASK;
    Flags |= FLAG_START_FALSE;
    Flags &= ~FLAG_PAUSE_MASK;
    Flags |= FLAG_PAUSE_FALSE;
    current_line=0;
//    work_x_data.clear();
//    work_y_data.clear();
//    WorkCurve->setData(work_x_data,work_y_data);
    preview_x_data.clear();
    preview_y_data.clear();
    PreviewCurve->setData(preview_x_data,preview_y_data);
}

void MainWindow::SelectNextLine()
{
    QString Line;
    if(current_line+1 < total_line)
    {
        current_line++;
        Line = QString(G_Code_list[current_line]);
        ProcessGCodeFormQString(&Line);
    }
    else
    {
        Flags &= ~FLAG_CNC_BUSY_MASK;
        Flags |= FLAG_CNC_BUSY_FALSE;
    }
}


void MainWindow::openFile(void)
{
    QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"),"/app",tr("Text File (*.txt)"));
    qDebug() << fileName;
    if(!fileName.isEmpty())
    {
        QFile file(fileName);
        if(!file.open(QFile::ReadOnly | QFile::Text))
        {
            QMessageBox::warning(this,tr("Warning!!"),tr("couldn't open file %1\n%2").arg(fileName).arg(file.errorString()));
        }
        else
        {
            G_Code_Stream.setDevice(&file);
            textEdit->setText(G_Code_Stream.readAll());
            Flags &= ~FLAG_FILE_OPENED_MASK;
            Flags |= FLAG_FILE_OPENED_TRUE;
            current_line = 0;
            total_line = textEdit->document()->lineCount();
            G_Code_list = textEdit->toPlainText().split("\n");
//            qDebug()<<QString(G_Code_list[0]);
            file.close();
        }
    }
}

void MainWindow::Close_Slot()
{
    textEdit->clear();
    work_x_data.clear();
    work_y_data.clear();
    preview_x_data.clear();
    preview_y_data.clear();
}

void MainWindow::PlotInit(QCustomPlot *ploter)
{
    this->PreviewCurve = ploter->addGraph();
    this->WorkCurve = ploter->addGraph();
    this->PreviewCurve->setPen(QPen(Qt::black));
    this->WorkCurve->setPen(QPen(Qt::red));

//    work_x_data.append(0);
//    work_x_data.append(1);
    this->WorkCurve->setData(work_x_data,work_y_data,true);
    this->PreviewCurve->setData(preview_x_data,preview_y_data,true);
//    ploter->replot();
    ploter->xAxis->setLabel("x");
    ploter->yAxis->setLabel("y");


}

void MainWindow::DrawPreView_AddPoint(float x,float y,float z)
{
//    this->PreviewCurve->addData(x,y);
    preview_x_data.append(x);
    preview_y_data.append(y);
    PreviewCurve->setData(preview_x_data,preview_y_data,true);
}

void MainWindow::DrawWork_AddPoint(float x,float y,float z)
{
    work_x_data.append(x);
    work_y_data.append(y);
//    widgetDrawArea->replot(QCustomPlot::rpQueuedReplot);
    WorkCurve->setData(work_x_data,work_y_data,true);
}

void MainWindow::MDI_Enter_Slot(void)
{
    std::string StdString;
    char *g_code_line_char;
    g_code_param_t ret_param;
    G_Code_Line = lineEdit_MDI->text();
    StdString = G_Code_Line.toStdString();
    g_code_line_char = const_cast<char*>(StdString.c_str());
    qDebug()<<g_code_line_char;
    g_code_get_param(g_code_line_char,&ret_param);
    lineEdit_MDI->clear();
//    for(int i=0;i<500;i++)
//    {
//        interpolator_Handler();
//    }

}

void extern_DrawWork_AddPoint(int x,int y,int z);
void extern_DrawPreview_AddPoint(int x,int y,int z);

void extern_feedspeed_handler(float speed);
void extern_mainsharftControl_handler(int status);
void extern_mainshaftSpeed_handler(float speed);
void extern_CoolingControl_handler(int status);
void MainWindow::C_CallbackConfig()
{
    CoolingControlRegister(&extern_CoolingControl_handler);
    FeedspeedControlRegister(&extern_feedspeed_handler);
    MainshaftControlRegister(&extern_mainsharftControl_handler);
    MainshaftSpeedControlRegister(&extern_mainshaftSpeed_handler);
}

void MainWindow::WorkGraphActive()
{
    TransactorRegister(&extern_DrawPreview_AddPoint);
}

void MainWindow::PreviewGraphActive()
{
    TransactorRegister(&extern_DrawWork_AddPoint);
}
void MainWindow::UI_Init()
{
    //    client = new QTcpSocket(this);
    //    client->connectToHost("127.0.0.1",11860);
        textEdit = new QTextEdit(this);
    //    textEdit->setEnabled(false);
        act_open = new QAction(this);
        QIcon icon;
        icon.addFile(":/res/image/open.png");
        act_open->setIcon(icon);
        act_open->setText(tr("Open file"));
        act_open->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));

        act_close = new QAction(this);
        QIcon icon1;
        icon1.addFile(":/res/image/close.png");
        act_close->setIcon(icon1);
        act_close->setText(tr("Close file"));

        act_exit = new QAction(this);
        QIcon icon2;
        icon2.addFile(":/res/image/exit.png");
        act_exit->setIcon(icon2);
        act_exit->setText(tr("Exit"));

        menuBar = new QMenuBar(this);
        menu_file = new QMenu(this);
        menu_file->setTitle(tr("File"));
        this->setMenuBar(menuBar);

        menu_edit = new QMenu(this);
        menu_edit->setTitle(tr("Edit"));

        menuBar->addMenu(menu_file);
        menuBar->addMenu(menu_edit);

        menu_file->addAction(act_open);
        menu_file->addAction(act_close);
        menu_file->addAction(act_exit);

        toolBar = new QToolBar(this);
        this->addToolBar(Qt::TopToolBarArea,toolBar);
        act_start = new QAction(this);
        QIcon Icon3;
        Icon3.addFile(":/res/image/start.png");
        act_start->setIcon(Icon3);
        act_start->setText(tr("Start"));

        act_pause = new QAction(this);
        QIcon Icon4;
        Icon4.addFile(":/res/image/pause.png");
        act_pause->setIcon(Icon4);
        act_pause->setText(tr("Pause"));

        act_stop = new QAction(this);
        QIcon Icon5;
        Icon5.addFile(":/res/image/stop.png");
        act_stop->setIcon(Icon5);
        act_stop->setText(tr("Stop"));

        toolBar->addAction(act_start);
        toolBar->addAction(act_pause);
        toolBar->addAction(act_stop);


        MDI_Label = new QLabel(this);
        MDI_Layout = new QVBoxLayout(this);
        MDI_Label->setText(tr("MDI(Enter)"));
        lineEdit_MDI = new QLineEdit(this);

        MDI_Layout->addWidget(MDI_Label);
        MDI_Layout->addWidget(lineEdit_MDI);
//        lineEdit_Test = new QLineEdit(this);
//        lineEdit_Test->setText(tr("Test"));

        widgetDrawArea = new QCustomPlot(this);
        widgetDrawArea->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
        PlotInit(widgetDrawArea);
    //    DrawPreView_AddPoint(0,0);

        FeedSpeedValue = new QLineEdit(this);
        FeedSpeedLabel = new QLabel(this);
        RotationLabel = new QLabel(this);
        RotationValue = new QLineEdit(this);
        CoolingStatusLabel = new QLabel(this);
        MainsharftStatusLabel = new QLabel(this);
        MainsharftStatusImage = new QLabel(this);
        CoolingStatusImage    = new QLabel(this);

        pixMapGreen = QPixmap(":/res/image/g.png").scaled(25, 25, Qt::KeepAspectRatio);
        pixMapRed   = QPixmap(":/res/image/r.png").scaled(25, 25, Qt::KeepAspectRatio);
        MainsharftStatusImage->setPixmap(pixMapRed);
        CoolingStatusImage->setPixmap(pixMapRed);



        CoolingStatusLabel->setText(tr("Cooling"));
        MainsharftStatusLabel->setText(tr("Mainshaft"));

        FeedSpeedLabel->setText(tr("FeedSpeed"));
        RotationLabel->setText(tr("MainshaftSpeed"));
        FeedSpeedValue->setText(tr("0"));
        RotationValue->setText(tr("0"));

        FeedSpeedLayout = new QHBoxLayout(this);
        SpindleSpeedLayout = new QHBoxLayout(this);
        SpindleStatusLayout = new QHBoxLayout(this);
        CoolingStatusLayout = new QHBoxLayout(this);

        FeedSpeedLayout->addWidget(FeedSpeedLabel);
        FeedSpeedLayout->addWidget(FeedSpeedValue);

        SpindleSpeedLayout->addWidget(RotationLabel);
        SpindleSpeedLayout->addWidget(RotationValue);

        SpindleStatusLayout->addWidget(MainsharftStatusLabel);
        SpindleStatusLayout->addWidget(MainsharftStatusImage);

        CoolingStatusLayout->addWidget(CoolingStatusLabel);
        CoolingStatusLayout->addWidget(CoolingStatusImage);

        StatusLayout = new QGridLayout(this);
        StatusLayout->addLayout(FeedSpeedLayout,0,0);
        StatusLayout->addLayout(SpindleStatusLayout,0,1);
        StatusLayout->addLayout(SpindleSpeedLayout,1,0);
        StatusLayout->addLayout(CoolingStatusLayout,1,1);

        MainLayout = new QGridLayout(this);

        MainLayout->addWidget(widgetDrawArea,0,0);
        MainLayout->addWidget(textEdit,0,1);
        MainLayout->addLayout(StatusLayout,1,0);
        MainLayout->addLayout(MDI_Layout,1,1);

        MainLayout->setRowStretch(0,8);
        MainLayout->setRowStretch(1,1);
        MainLayout->setColumnStretch(0,2);
        MainLayout->setColumnStretch(1,1);
        QWidget *CentralWidget = new QWidget(this);
        CentralWidget->setLayout(MainLayout);
        this->setCentralWidget(CentralWidget);

        this->setMinimumSize(860,640);
}
